package com.neuedu.qian.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neuedu.qian.entity.User;
import com.neuedu.qian.mapper.UserMapper;
import com.neuedu.qian.service.IUserService;
import com.neuedu.qian.util.RedisUtils;
import com.neuedu.qian.util.SignUtils;
import com.neuedu.qian.vo.ResponseData;
import com.neuedu.qian.vo.UserVO;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private HttpServletRequest request;

    @Override
    public ResponseData login(String account, String password) {
        //判断用户是否被锁定
        String lockKey = "user:login:lock:" + account;
        if (redisUtils.hasKey(lockKey)) {
            return ResponseData.fail(999, "该用户已被锁定,请稍后再试");
        }
        if (StrUtil.isEmpty(account)) {
            return ResponseData.fail(999, "请输入用户名或工号或手机号码或邮箱");
        }
        if (StrUtil.isEmpty(password)) {
            return ResponseData.fail(999, "密码不能为空");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("password", password);
        queryWrapper.and(qw -> {
            qw.eq("username", account);
            qw.or();
            qw.eq("email", account);
            qw.or();
            qw.eq("mobile", account);
            qw.or();
            qw.eq("work_no", account);
        });
        User user = getBaseMapper().selectOne(queryWrapper);
        if (user == null) {
            //登录失败
            String failKey = "user:login:fail:" + account;
            //将登录失败错误次数+1,如果是第一次错误,返回1
            long counter = redisUtils.incr(failKey, 1);
            if (1 == counter) {
                //如果是第一次错误，将有效期设置为60秒
                redisUtils.expire(failKey, 60);
            }
            if (counter > 5) {
                //锁定用户,key:user:lock:username,value:1,过期时间:2小时.value为任意值
                redisUtils.set(lockKey, account, 60 * 60 * 2);
                return ResponseData.fail(999, "该用户已被锁定,请2小时后再试");
            }
            return ResponseData.fail(999, "用户名或密码错误" + counter + "次,超过5次后锁定2小时");
        }
        //判断用户状态
        if (9 == user.getDeleteStatus()) {
            return ResponseData.fail(999, "该用户已被禁用");
        }
        String id=user.getAdminId().toString();
        //判断该用户是否重复登录
        String loginKey = "user:login:id:" + id;
        if (redisUtils.hasKey(loginKey)) {
            return ResponseData.fail(999, "该用户已在其他地方登录");
        }
        //登录成功,向redis中添加标记,作用:标记该用户已登录
        redisUtils.set(loginKey, id, 60 * 60 * 24 * 15);
        //登录令牌
        String token = SignUtils.getToken(id, request);
        UserVO userVO = new UserVO();
        userVO.setUserId(user.getAdminId());
        userVO.setName(user.getUsername());
        userVO.setCode(user.getWorkNo());
        userVO.setRole(UserVO.Role.SYS);
        userVO.setToken(token);
        //登录成功,向会话或redis中保存用户的信息.key:"user:token:"+token,value:用户信息，时间为:15天
        redisUtils.set("user:token:"+token,userVO,60 * 60 * 24 * 15);
        return ResponseData.success(token);
    }
}